using System;
using System.Security;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace OfficeClip.OpenSource.Utility
{
 public class Log
 {
	private string filePath;
	private StreamWriter sw = null;
  private bool _isErrors = false;
  private bool _isDisposed = false;
  private bool _deleteOnExit = false;
     private LogLevel logLevel = LogLevel.ALL;

	public Log(string folder, int purgeFileDays)
	{
	 // make sure that the folder exists
	 if (!Directory.Exists(folder))
	 {
		Directory.CreateDirectory(folder);
	 }
	 OpenSource.Utility.Constants.ProvideFullAccess(folder);
	 // Now remove all the files that are older than 2 days
	 foreach (string str in Directory.GetFiles(folder))
	 {
		if (File.GetCreationTime(str) < DateTime.Now.AddDays(-1 * purgeFileDays))
		{
		 File.Delete(str);
		}
	 }
	 // Create the new file
	 filePath = string.Format(@"{0}\log.{1}.{2}.html", folder, 
		DateTime.Now.ToString("yyyyMMdd"), DateTime.Now.ToString("HHmmss"));
	 sw = File.AppendText(filePath);
	 sw.WriteLine(@"<html>");
	 sw.WriteLine(@"<head>");
	 sw.WriteLine(@"<style>td{font-family: sans-serif, arial;font-size: x-small;vertical-align:top}</style>");
	 sw.WriteLine(@"</head>");
	 sw.WriteLine(@"<body>");
	 sw.WriteLine(@"<b>" + DateTime.Now.ToString("MMM dd, yyyy hh:mm:ss tt") + ": Start Log" + "</b>");
	 sw.WriteLine(@"<P><table cellspacing=""1"" border=""1"">");
	 sw.Flush();
	}

  public void Dispose()
  {
   try
   {
    _isDisposed = true;
    sw.Close();
    sw.Dispose();
    sw = null;
    if (_isErrors || !_deleteOnExit)
    {
     sw = File.AppendText(filePath);
     sw.WriteLine(@"</table></P>");
     sw.WriteLine(@"</body>");
     sw.WriteLine(@"</html>");
     sw.Flush();
     sw.Close();
     sw.Dispose();
    }
    else
    {
     if (_deleteOnExit)
      File.Delete(filePath);
    }
   }
   catch
   {
   }
  }

  ~Log()
  {
   if (!_isDisposed)
    Dispose();
  }

  public bool DeleteOnExit
  {
   set { _deleteOnExit = value; }
   get { return _deleteOnExit; }
  }


	public void Flush()
	{
	 sw.Flush();
	}

	private string GetRowColor(LogState state)
	{
	 string retVal = "White";
	 switch (state)
	 {
		case LogState.Debug:
		 retVal = "LightBlue";
		 break;
    case LogState.Event:
     retVal = "Yellow";
     break;
		case LogState.Warning:
		 retVal = "Lavender";
		 break;
		case LogState.Pass:
		 retVal = "LightGreen";
		 break;
		case LogState.Title:
		 retVal = "Khaki";
		 break;
		case LogState.SubTitle:
		 retVal = "LightGrey";
		 break;
		case LogState.Error:
		 retVal = "LightPink";
		 break;
     	case LogState.FatalError:
		 retVal = "Violet";
		 break;
	 }
	 return retVal;
	}

	public string GetLogStateString(LogState state)
	{
	 return state.ToString();
	}

	protected LogState GetLogStateFromSeverity(int severity)
	{
	 LogState state = LogState.None; // for severity level upto 10
	 switch (severity)
	 {
		case 11:
		case 12:
		case 13:
		case 14:
		case 15:
		case 16:
		case 17:
		case 18:
		 state = LogState.Error;
		 break;
		case 19:
		case 20:
		case 21:
		case 22:
		case 23:
		case 24:
		case 25:
		 state = LogState.FatalError;
		 break;
	 }
	 return state;
	}

	public void Write(int lineNum, int errorClass, int errorNum, string str)
	{
	 LogState state = GetLogStateFromSeverity(errorClass);
	 string topic = "Sql Server";
	 string description = string.Format(
		"Line#: {0}, Class: {1}, Number: {2}: {3}", lineNum, errorClass, errorNum, str
	 );
	 Write(state, topic, description);
	}

  public void WriteProperty(string propertyName,string propertyDescription)
  {
      if (logLevel < LogLevel.DEBUG)
      {
          return;
      }
   Write(LogState.Property, propertyName, propertyDescription);
  }

	public void WriteFunction(string functionName,
	 string arg1, string arg2, string arg3, string argRest)
	{
        if (logLevel < LogLevel.INFO)
        {
            return;
        }
   string desc = string.Format("({0}, {1}, {2}, {3})", arg1, arg2, arg3, argRest);
   Write(LogState.Function, functionName, desc);
	}

  public void WriteEvent(string title, string description)
  {
      if (logLevel < LogLevel.INFO)
      {
          return;
      }
   Write(LogState.Event, title, description);
  }

	public void WriteInfo(string title, string description)
	{
        if (logLevel < LogLevel.INFO)
        {
            return;
        }
	 Write(LogState.Info, title, description);
	}


     public void WriteDebug(string title, string description)
     {
         if (logLevel < LogLevel.DEBUG)
         {
             return;
         }
         Write(LogState.Debug, title, description);
     }

	public void WriteError(string title, string description)
	{
        if (logLevel < LogLevel.ERROR)
        {
            return;
        }
   _isErrors = true;
	 Write(LogState.Error, title, description);
	}

     public void WriteFatalError(string title, string description)
     {
         if (logLevel < LogLevel.FATAL)
         {
             return;
         }
         _isErrors = true;
         Write(LogState.FatalError, title, description);
     }

     public void WriteWarning(string title, string description)
     {
         if (logLevel < LogLevel.WARNING)
         {
             return;
         }
        
         Write(LogState.Warning, title, description);
     }
	public void WritePass(string title, string description)
	{
        
	 Write(LogState.Pass, title, description);
	}

	public void WriteSubTitle(string title, string description)
	{
	 Write(LogState.SubTitle, title, description);
	}

	public void Write(LogState state, string topic, string description)
	{
	 StringBuilder sb = new StringBuilder();
	 try
	 {
		switch (state)
		{
		 case LogState.Title:
		 case LogState.SubTitle:
			sb.Append(@"<tr bgcolor=""");
			sb.Append(GetRowColor(state));
			sb.Append(@"""><td nowrap colspan=""4"">");
			sb.Append(DateTime.Now.ToString("MMM dd, yyyy hh:mm:ss tt"));
			sb.Append(@":&nbsp;<b>");
			sb.Append(topic);
			sb.Append(@"</b>&nbsp;");
			sb.Append(description);
			sb.Append(@"</td></tr>");
			break;
		 default:
			sb.Append(@"<tr bgcolor=""");
			sb.Append(GetRowColor(state));
			sb.Append(@"""><td nowrap>");
			sb.Append(DateTime.Now.ToString("hh:mm:ss.FFF"));
			sb.Append("</td>");
			sb.Append(@"<td nowrap valign=""top"">");
			sb.Append(GetLogStateString(state));
			sb.Append("</td>");
			sb.Append(@"<td nowrap valign=""top"">");
			sb.Append(topic);
			sb.Append("</td>");
			sb.Append(@"<td valign=""top"">");
			sb.Append((description != null) ? description.Replace("\r\n", "<br>") : "null");
			sb.Append("</td></tr>");
			break;
		}
		sw.WriteLine(sb.ToString());
		sw.Flush();
	 }
	 catch (Exception e)
	 {
		throw new Exception("Log File could not be written into: ", e);
	 }
	}

     public void SetLogLevel(LogLevel level)
     {
         this.logLevel = level;
     }

     public LogLevel GetLogLevel()
     {
         return logLevel;
     }
 }
}
